package com.kuzlak.cms.module.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kuzlak.cms.model.PermissionSqlModel;
import com.kuzlak.cms.module.sys.entity.SysMenu;
import com.kuzlak.cms.module.sys.mapper.SysMenuMapper;
import com.kuzlak.cms.module.sys.model.DataModel;
import com.kuzlak.cms.module.sys.service.SysMenuService;
import com.kuzlak.cms.utils.RedisClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* @author hesenjan
* @description 针对表【sys_menu】的数据库操作Service实现
* @createDate 2024-11-30 23:46:05
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>
    implements SysMenuService{

    @Autowired
    private RedisClient redisUtil;

    @Cacheable(value = "menu", cacheNames = "menu", key = "'findByDataList::'+#userId")
    @Override
    public List<Map<String, Object>> findByDataList(long userId, String name) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysMenu::getDeleted, 0).eq(SysMenu::getParentId, 0);
        if (StringUtils.isNotEmpty(name)) {
           // queryWrapper.lambda().inSql(SysMenu::getId, PermissionSqlModel.serachName(name));
        }

        if (userId > 0) {
           // queryWrapper.lambda().inSql(SysMenu::getId, PermissionSqlModel.menus(userId));
        }


        List<SysMenu> data = this.list(queryWrapper);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            Map<String, Object> category = DataModel.getCategory(next);
            QueryWrapper<SysMenu> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(SysMenu::getDeleted, 0).eq(SysMenu::getParentId, next.getId());
            if (userId > 0) {
                queryWrapper1.lambda().inSql(SysMenu::getId, PermissionSqlModel.menus(userId));
            }
            if (StringUtils.isNotEmpty(name)) {
                queryWrapper1.lambda().inSql(SysMenu::getId, PermissionSqlModel.serachName(name));
            }
            List<Map<String, Object>> cheldren = getCheldren(userId, queryWrapper1, name);
            if (!cheldren.isEmpty()) {
                category.put("children", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

    private List<Map<String, Object>> getCheldren(long userId, QueryWrapper<SysMenu> queryWrapper, String name) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<SysMenu> data = this.list(queryWrapper);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            QueryWrapper<SysMenu> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(SysMenu::getDeleted, 0).eq(SysMenu::getParentId, next.getId());
            if (StringUtils.isNotEmpty(name)) {
                queryWrapper1.lambda().inSql(SysMenu::getId, PermissionSqlModel.serachName(name));
            }
            if (userId > 0) {
                queryWrapper1.lambda().inSql(SysMenu::getId, PermissionSqlModel.menus(userId));
            }
            Map<String, Object> category = DataModel.getCategory(next);
            List<Map<String, Object>> cheldren = getCheldren(userId, queryWrapper1, name);
            if (!cheldren.isEmpty()) {
                category.put("children", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

    @Cacheable(value = "menu", cacheNames = "menu", key = "'findByDataAdminList::'+#userId")
    @Override
    public List<Map<String, Object>> findByDataAdminList(long userId, String name) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysMenu::getDeleted, 0).eq(SysMenu::getParentId, 0);
        if (StringUtils.isNotEmpty(name)) {
            queryWrapper.lambda().inSql(SysMenu::getId, PermissionSqlModel.serachName(name));

        }

        List<SysMenu> data = this.list(queryWrapper);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            QueryWrapper<SysMenu> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(SysMenu::getDeleted, 0).eq(SysMenu::getParentId, next.getId());
            if (StringUtils.isNotEmpty(name)) {
                queryWrapper1.lambda().inSql(SysMenu::getId, PermissionSqlModel.serachName(name));
            }
            Map<String, Object> category = DataModel.getCategory(next);
            List<Map<String, Object>> cheldren = getCheldrenAdmin(queryWrapper1, name);
            if (!cheldren.isEmpty()) {
                category.put("children", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

    @Cacheable(value = "menu", cacheNames = "menu", key = "'findByDataAdminMenuList::'+#userId")
    @Override
    public List<Map<String, Object>> findByDataAdminMenuList(Long userId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<SysMenu> data = this.baseMapper.findByDataAdminMenuList(0L);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            Map<String, Object> category = DataModel.getMenu(next);
            List<Map<String, Object>> cheldren = getCheldrenMenuAdmin(next.getId());
            if (!cheldren.isEmpty()) {
                category.put("routes", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> findByDataMenuList(Long userId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<SysMenu> data = this.baseMapper.findByDataMenuList(userId, 0L);

        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            Map<String, Object> category = DataModel.getMenu(next);
            List<Map<String, Object>> cheldren = getMenuCheldren(userId, next.getId());
            if (!cheldren.isEmpty()) {
                category.put("routes", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

    @Override
    public List<String> findByDataAdminKeyList() {

        List<String> byDataAdminKeyList = this.baseMapper.findByDataAdminKeyList();

        return byDataAdminKeyList;
    }

    @Override
    public List<String> findByDataKeyList(Long userId) {
        List<String> byDataAdminKeyList = this.baseMapper.findByDataKeyList(userId);

        return byDataAdminKeyList;
    }

    @Override
    public List<String> findByDataKeyPerList(Long userId) {

        List<String> byDataAdminKeyList = null;


        byDataAdminKeyList = this.baseMapper.findByDataPerKeyList(userId);


        return byDataAdminKeyList;
    }

    @Override
    public List<String> findByDataPerKeyAdminList() {

        List<String> byDataAdminKeyList = null;


        byDataAdminKeyList = this.baseMapper.findByDataPerKeyAdminList();


        return byDataAdminKeyList;
    }


    @CacheEvict(value = "menu:*")
    @Override
    public boolean deleteById(long id) {
        int i = this.baseMapper.deleteById(id);
        //System.out.println("DELEDDDDD:" + i);
        //System.out.println("DELEDDDDD_FLAG:" + (i != 0));
        redisUtil.delAll("menu");
        return (i != 0);
    }

    @Override
    public List<Map<String, Object>> findByDataAdminKeyDataList() {
        List<Map<String, Object>> byDataAdminKeyList = this.baseMapper.findByDataAdminKeyDataList();

        return byDataAdminKeyList;
    }

    @Override
    public List<Map<String, Object>> findByDataKeyDataList(Long userId) {
        List<Map<String, Object>> byDataAdminKeyList = this.baseMapper.findByDataKeyDataList(userId);

        return byDataAdminKeyList;
    }


    private List<Map<String, Object>> getCheldrenAdmin(QueryWrapper<SysMenu> queryWrapper, String name) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<SysMenu> data = this.list(queryWrapper);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            QueryWrapper<SysMenu> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(SysMenu::getDeleted, 0).eq(SysMenu::getParentId, next.getId());
            if (StringUtils.isNotEmpty(name)) {
                queryWrapper1.lambda().inSql(SysMenu::getId, PermissionSqlModel.serachName(name));
            }
            Map<String, Object> category = DataModel.getCategory(next);
            List<Map<String, Object>> cheldren = getCheldrenAdmin(queryWrapper1, name);
            if (!cheldren.isEmpty()) {
                category.put("children", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }


    private List<Map<String, Object>> getCheldrenMenuAdmin(long parentId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<SysMenu> data = this.baseMapper.findByDataAdminMenuList(parentId);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            Map<String, Object> category = DataModel.getMenu(next);
            List<Map<String, Object>> cheldren = getCheldrenMenuAdmin(next.getId());
            if (!cheldren.isEmpty()) {
                category.put("routes", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

    private List<Map<String, Object>> getMenuCheldren(long userId, long parentId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<SysMenu> data = this.baseMapper.findByDataMenuList(userId, parentId);
        Iterator<SysMenu> iterator = data.iterator();
        while (iterator.hasNext()) {
            SysMenu next = iterator.next();
            Map<String, Object> category = DataModel.getMenu(next);
            List<Map<String, Object>> cheldren = getMenuCheldren(userId, next.getId());
            if (!cheldren.isEmpty()) {
                category.put("routes", cheldren);
            }
            mapList.add(category);
        }
        return mapList;
    }

}









